\subsubsection{ARM}

\myparagraph{\OptimizingKeilVI (\ThumbMode)}

\lstinputlisting[style=customasmARM]{patterns/04_scanf/1_simple/ARM_IDA.lst}

\myindex{\CLanguageElements!\Pointers}
Чтобы \scanf мог вернуть значение, ему нужно передать указатель на переменную типа \Tint.
\Tint~--- 32-битное значение, для его хранения нужно только 4 байта, и оно помещается в 32-битный регистр.

\myindex{IDA!var\_?}
Место для локальной переменной \GTT{x} выделяется в стеке, \IDA наименовала её \IT{var\_8}. 
Впрочем, место для неё выделять не обязательно, т.к. \glslink{stack pointer}{указатель стека} \ac{SP} уже указывает на место, 
свободное для использования.
Так что значение указателя \ac{SP} копируется в регистр \Reg{1}, и вместе с format-строкой, 
передается в \scanf.

\myindex{ARM!\Instructions!LDR}
Позже, при помощи инструкции \INS{LDR}, это значение перемещается из стека в регистр \Reg{1}, чтобы быть переданным в \printf.

\myparagraph{ARM64}

\lstinputlisting[caption=\NonOptimizing GCC 4.9.1 ARM64,numbers=left,style=customasmARM]{patterns/04_scanf/1_simple/ARM64_GCC491_O0_RU.s}

Под стековый фрейм выделяется 32 байта, что больше чем нужно. Может быть, это связано с выравниваем по границе памяти?
Самая интересная часть~--- это поиск места под переменную $x$ в стековом фрейме (строка 22).
Почему 28? Почему-то, компилятор решил расположить эту переменную в конце стекового фрейма, а не в начале.
Адрес потом передается в \scanf, которая просто сохраняет значение, введенное пользователем, в памяти по этому адресу.
Это 32-битное значение типа \Tint.
Значение загружается в строке 27 и затем передается в \printf.

